<title>InputEvent: macOS Transpose</title>
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<script src='../../../editing/assert_selection.js'></script>
<div id="editable" contenteditable></div>
<textarea id="txt"></textarea>
<script>
test(() => {
    assert_not_equals(window.testRunner, undefined, 'This test requires testRunner.');

    let eventRecorder = '';
    document.addEventListener('beforeinput', event => {
        const range = event.getTargetRanges()[0];
        eventRecorder += `beforeinput-${event.inputType}-${event.data}-${range.startOffset}-${range.endOffset}-`;
    });
    document.addEventListener('input', event => {
        eventRecorder += `input-${event.inputType}`;
    });

    const editable = document.getElementById('editable');
    editable.innerHTML = 'abc';
    editable.focus();
    const selection = window.getSelection();
    selection.collapse(editable, 1); // End of first line.

    // Test Transpose.
    eventRecorder = '';
    testRunner.execCommand('transpose');
    assert_equals(editable.innerHTML, 'acb');
    assert_equals(eventRecorder, 'beforeinput-insertTranspose-cb-1-3-input-insertTranspose');
}, 'Transpose on contenteditable');

test(() => {
    assert_not_equals(window.testRunner, undefined, 'This test requires testRunner.');

    let eventRecorder = '';
    document.addEventListener('beforeinput', event => {
        eventRecorder += `beforeinput-${event.inputType}-${event.data}-`;
    });
    document.addEventListener('input', event => {
        eventRecorder += `input-${event.inputType}`;
    });

    const txt = document.getElementById('txt');
    txt.value = 'abc';
    txt.focus();
    txt.setSelectionRange(3, 3); // End of first line.

    // Test Transpose.
    eventRecorder = '';
    testRunner.execCommand('transpose');
    assert_equals(txt.value, 'acb');
    assert_equals(eventRecorder, 'beforeinput-insertTranspose-cb-input-insertTranspose');
}, 'Transpose on <textarea>');

test(() => {
    assert_not_equals(window.testRunner, undefined, 'This test requires testRunner.');

    assert_selection(
        '<div contenteditable id="editable1">a|bc</div>',
        (selection, testRunner) => {
            const editable1 = selection.document.getElementById('editable1');
            editable1.addEventListener('beforeinput', event => {
                event.preventDefault();
            });
            testRunner.execCommand('transpose');
        },
        '<div contenteditable id="editable1">a|bc</div>');
}, 'Transpose should not modify selection when canceled');

test(() => {
    assert_not_equals(window.testRunner, undefined, 'This test requires testRunner.');

    assert_selection(
        '<div contenteditable id="editable1">a|bc</div>',
        (selection, testRunner) => {
            const editable1 = selection.document.getElementById('editable1');
            editable1.addEventListener('beforeinput', event => {
                selection.collapse(editable1, 1); // End of first line.
            });
            testRunner.execCommand('transpose');
        },
        '<div contenteditable id="editable1">acb|</div>');
}, 'Transpose should still apply when selection changed');
</script>
